import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lib_core/lib_core.dart';
import 'package:lib_ui/gen/assets.gen.dart';

import '../gen/colors.gen.dart';

enum LDTextFieldType { none, arrow, clear, password, overLimit }

class LDTextField extends StatefulWidget {
  final TextEditingController? controller;
  final String? text;
  final FontWeight fontWeight;
  final double fontSize;
  final String? hint;
  final String? leadingText;
  final Widget? leadingIcon;
  final Color? backgroundColor;
  final int? maxLength;
  final int? maxLine;
  final bool enable;
  final TextInputType? keyboardType;
  final TextInputAction? textInputAction;
  final bool autofocus;
  final LDTextFieldType type;
  final ValueChanged<String>? onTextChanged;
  final ValueChanged<String>? onSubmitted;

  const LDTextField({
    Key? key,
    this.controller,
    this.text,
    this.fontSize = 16,
    this.fontWeight = FontWeight.normal,
    this.hint,
    this.leadingText,
    this.leadingIcon,
    this.backgroundColor,
    this.maxLength,
    this.maxLine,
    this.enable = true,
    this.keyboardType,
    this.textInputAction,
    this.autofocus = false,
    this.type = LDTextFieldType.none,
    this.onTextChanged,
    this.onSubmitted,
  }) : super(key: key);

  @override
  State<LDTextField> createState() => _LDTextFieldState();
}

class _LDTextFieldState extends State<LDTextField> {
  final border = OutlineInputBorder(
    borderSide: const BorderSide(color: Colors.transparent),
    borderRadius: BorderRadius.circular(8),
  );

  final _showClear = false.obs;
  final _visible = true.obs;

  final _overLimit = 0.obs;

  late TextEditingController _ctrl;

  @override
  void initState() {
    super.initState();
    _ctrl = (widget.controller ??
        TextEditingController.fromValue(TextEditingValue(
          text: widget.text ?? '',
          selection: TextSelection.fromPosition(TextPosition(offset: widget.text?.length ?? 0)),
        )))
      ..addListener(() {
        _showClear.value = _ctrl.text.isNotEmpty;
        _overLimit.value = widget.maxLength == null ? 0 : widget.maxLength! - _ctrl.text.length;

        widget.onTextChanged?.call(_ctrl.text);
      });
    _showClear.value = (widget.text ?? '').isNotEmpty;

    _visible.value = widget.type != LDTextFieldType.password;
  }

  @override
  void didUpdateWidget(covariant LDTextField oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 原本是_ctrl.text = widget.text ?? ''，但当弹出的是sheet并且sheet里有该组件，
    // 当软键盘显示或关闭时会触发didUpdateWidget，这样会导致输入完之后关闭键盘会被清空
    _ctrl.text = widget.text ?? (_ctrl.text == '' ? '' : _ctrl.text);
    _ctrl.selection = TextSelection.fromPosition(TextPosition(offset: _ctrl.text.length));
  }

  @override
  void dispose() {
    if (widget.controller == null) {
      _ctrl.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final children = <Widget>[
      Expanded(
        child: Obx(() {
          return TextField(
            controller: _ctrl,
            autofocus: widget.autofocus,
            style: TextStyle(
              fontSize: widget.fontSize,
              fontWeight: widget.fontWeight,
              color: ColorName.textPrimary,
              height: 1.2,
            ),
            decoration: InputDecoration(
              hintText: widget.hint,
              hintStyle: const TextStyle(
                fontSize: 16,
                color: ColorName.textHint,
                height: 1.2,
              ),
              border: InputBorder.none,
              contentPadding: const EdgeInsets.symmetric(vertical: 19),
              isDense: true,
            ),
            buildCounter: (
              BuildContext context, {
              required int currentLength,
              int? maxLength,
              required bool isFocused,
            }) {
              return null;
            },
            enabled: widget.enable,
            maxLength: widget.type == LDTextFieldType.overLimit ? null : widget.maxLength,
            maxLines: widget.type == LDTextFieldType.password ? 1 : widget.maxLine,
            keyboardType: widget.keyboardType,
            inputFormatters: widget.keyboardType == TextInputType.number ? <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly,] : null,
            textInputAction: widget.textInputAction,
            obscureText: !_visible.value,
            onSubmitted: widget.onSubmitted,
          );
        }),
      )
    ];

    if (widget.leadingText != null) {
      children.insertAll(0, [
        Text(
          widget.leadingText!,
          style: const TextStyle(color: Color(0xFF5F626C), fontSize: 16),
        ),
        Container(
          width: 1,
          height: 15,
          color: const Color(0x335E626D),
          margin: const EdgeInsets.symmetric(horizontal: 10),
        )
      ]);
    } else if (widget.leadingIcon != null) {
      children.insert(
        0,
        Container(
          margin: const EdgeInsets.only(right: 12),
          child: widget.leadingIcon!,
        ),
      );
    }

    switch (widget.type) {
      case LDTextFieldType.none:
        break;
      case LDTextFieldType.arrow:
        children.add(
          UIAssets.images.icArrowForward.svg(
            width: 24,
            height: 24,
            color: ColorName.textPrimary.withOpacity(0.2),
          ),
        );
        break;
      case LDTextFieldType.clear:
        children.add(Obx(() {
          return Visibility(
            visible: _showClear.value,
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () => _ctrl.clear(),
              child: Opacity(
                opacity: 0.2,
                child: UIAssets.images.icClear.svg(width: 24, height: 24),
              ),
            ),
          );
        }));
        break;
      case LDTextFieldType.password:
        children.add(GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: () => _visible.toggle(),
            child: Opacity(
              opacity: 0.2,
              child: Obx(() {
                return _visible.value
                    ? UIAssets.images.icInvisible.svg(width: 24, height: 24)
                    : UIAssets.images.icVisible.svg(width: 24, height: 24);
              }),
            )));
        break;
      case LDTextFieldType.overLimit:
        if (widget.maxLength != null) {
          children.add(Obx(() {
            return Visibility(
              visible: _overLimit.value < 0 ,
              child: Container(
                margin: EdgeInsets.only(left: 10),
                child: Text(
                  _overLimit.value.toString(),
                  style: const TextStyle(fontSize: 14, color: ColorName.accent),
                ),
              ),
            );
          }));
        }
        break;
    }

    return Container(
      padding: EdgeInsets.only(left: widget.leadingIcon != null ? 12 : 16.5, right: 9),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(7.5),
        color: widget.backgroundColor ?? const Color(0xFFF6F6F6),
      ),
      child: Row(children: children),
    );
  }
}
